﻿using LiteDB;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;

namespace LiteDBDemo
{
    internal class LiteDBHelper<T> : IDisposable
    {
        public static string dbName = "LiteDB.ldb";
        private static string datasource = $@"{System.Windows.Forms.Application.StartupPath}/Data/LiteDB.ldb";//连接字符串
        private static string tableName = string.Empty;
        ///所有的liteDB列表。
        public LiteCollection<T> liteDB
        {
            get
            {
                using (var db = new LiteDatabase(datasource))
                {
                    return (LiteCollection<T>)db.GetCollection<T>(tableName);
                }
            }
        }

        /// <summary>
        /// 创建一个LiteDB对象，有一个参数表明对应的文件路径。
        /// </summary>
        /// <param name="dbpath">对应数据库文件的路径，默认位置为程序目录下"mydata.ldb"</param>
        public LiteDBHelper(string table)
        {
            tableName = table;
            Instance();
        }
        /// <summary>
        /// 初始化
        /// </summary>
        private void Instance()
        {
            try
            {
                //string dbName, string password
                string path = System.Windows.Forms.Application.StartupPath + @"/Data/";
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                string databaseFileName = path + dbName;
                if (!File.Exists(databaseFileName))
                {
                    //创建一个FileInfo对象
                    FileInfo file = new FileInfo(datasource);
                    //创建文件
                    FileStream fs = file.Create();

                    //关闭文件流
                    fs.Close();
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("初始化异常", ex);
            }
        }

        /// <summary>
        /// 插入数据
        /// </summary>
        /// <typeparam name="T">操作的表名称</typeparam>
        /// <param name="entity"> 实体对象 </param>
        /// <returns>返回bool</returns>
        public int Insert(T entity)
        {
            BsonValue result = 0;
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    result = db.GetCollection<T>(tableName).Insert(entity);
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("插入数据异常", ex);
            }
            return Convert.ToInt32(result.RawValue);
        }

        /// <summary>
        /// 批量插入数据
        /// </summary>
        /// <typeparam name="T">操作的表名称</typeparam>
        /// <param name="entity"> 实体对象 </param>
        /// <returns>返回bool</returns>
        public int InsertAll(List<T> entity)
        {
            BsonValue result = 0;
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    result = db.GetCollection<T>(tableName).Insert(entity);
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("批量插入数据异常", ex);
            }
            return Convert.ToInt32(result.RawValue);
        }

        /// <summary>
        /// 修改数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns></returns>
        public bool Update(T entity)
        {
            bool result = false;
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    result = db.GetCollection<T>(tableName).Update(entity);
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("修改数据异常", ex);
            }
            return result;
        }
        /// <summary>
        /// 根据条件修改数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public int UpdateMany(Expression<Func<T, T>> entity = null, Expression<Func<T, bool>> whereLambda = null)
        {
            int result = 0;
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    result = db.GetCollection<T>(tableName).UpdateMany(entity, whereLambda);
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("根据条件修改数据异常", ex);
            }
            return result;
        }

        /// <summary>
        /// 查找全部数据
        /// </summary>
        /// <returns></returns>
        public List<T> QueryAll()
        {
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    return db.GetCollection<T>(tableName).FindAll().ToList();
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("查找全部数据异常", ex);
            }
            return new List<T>();
        }

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public List<T> QueryData(Expression<Func<T, bool>> whereLambda = null)
        {
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    return db.GetCollection<T>(tableName).Find(whereLambda).ToList();
                }
            }
            catch (Exception ex)
            {
               // LogHelper.Error("查询数据异常", ex);
            }
            return new List<T>();
        }

        /// <summary>
        /// 查询并排序(升序)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <param name="sortLambda"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public List<T> QueryDataOrderByAsc<TOder>(Expression<Func<T, bool>> whereLambda = null, Expression<Func<T, TOder>> sortLambda = null, int limit = 10)
        {
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    if (limit > 0)
                        return db.GetCollection<T>(tableName).Query().Where(whereLambda).OrderBy(sortLambda).Limit(limit).ToList();
                    else
                        return db.GetCollection<T>(tableName).Query().Where(whereLambda).OrderBy(sortLambda).ToList();
                }
            }
            catch (Exception ex)
            {
               // LogHelper.Error("查询并排序(升序)异常", ex);
            }
            return new List<T>();
        }

        /// <summary>
        /// 查询并排序(降序)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <param name="sortLambda"></param>
        /// <param name="limit"></param>
        /// <returns></returns>
        public List<T> QueryDataOrderByDesc<TOder>(Expression<Func<T, bool>> whereLambda = null, Expression<Func<T, TOder>> sortLambda = null, int limit = 10)
        {
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    if (limit > 0)
                        return db.GetCollection<T>(tableName).Query().Where(whereLambda).OrderByDescending(sortLambda).Limit(limit).ToList();
                    else
                        return db.GetCollection<T>(tableName).Query().Where(whereLambda).OrderByDescending(sortLambda).ToList();
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("查询并排序(降序)异常", ex);
            }
            return new List<T>();
        }
        /// <summary>分页获取记录</summary>
        /// <typeparam name="TOder">排序字段类型</typeparam>
        /// <param name="predicate">linq查询表达式</param>
        /// <param name="orderSelector">排序表达式</param>
        /// <param name="isDescending">是否降序,true降序</param>
        /// <param name="pageSize">每页大小</param>
        /// <param name="pageIndex">要获取的页码，从1开始</param>
        /// <returns>分页后的数据</returns>
        public List<T> QueryDataByPage<TOder>(Expression<Func<T, bool>> predicate, Func<T, TOder> orderSelector, Boolean isDescending, int pageSize, int pageIndex)
        {
            using (var db = new LiteDatabase(datasource))
            {
                var allCount = db.GetCollection<T>(tableName).Count(predicate); //计算总数
                var pages = (int)Math.Ceiling((double)allCount / (double)pageSize); //计算页码
                if (pageIndex > pages) return new List<T>();
                if (isDescending) //降序
                {
                    return db.GetCollection<T>(tableName).Find(predicate)
                                  .OrderByDescending(orderSelector)
                                  .Skip((pageIndex - 1) * pageSize)
                                  .Take(pageSize).ToList();
                }
                else  //升序
                {
                    return db.GetCollection<T>(tableName).Find(predicate)
                                 .OrderBy(orderSelector)
                                 .Skip((pageIndex - 1) * pageSize)
                                 .Take(pageSize).ToList();
                }
            }
        }
        /// <summary>
        /// 按条件查询一个数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public T QueryFirst(Expression<Func<T, bool>> whereLambda = null)
        {
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    return db.GetCollection<T>(tableName).FindOne(whereLambda);
                }
            }
            catch (Exception ex)
            {
                //LogHelper.Error("按条件查询一个数据异常", ex);
            }
            return default(T);
        }

        /// <summary>
        /// 按条件删除数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public int Delete(Expression<Func<T, bool>> whereLambda = null)
        {
            int result = 0;
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    result = db.GetCollection<T>(tableName).DeleteMany(whereLambda);
                }
            }
            catch (Exception ex)
            {
               // LogHelper.Error("按条件删除数据异常", ex);
            }
            return result;
        }

        /// <summary>
        /// 删除全部数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="whereLambda"></param>
        /// <returns></returns>
        public int DeleteAll()
        {
            int result = 0;
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    result = db.GetCollection<T>(tableName).DeleteAll();
                }
            }
            catch (Exception ex)
            {
               // LogHelper.Error("删除全部数据异常", ex);
            }
            return result;
        }

        /// <summary>
        /// 重建数据库文件(收缩文件大小)
        /// </summary>
        public void Rebuild()
        {
            try
            {
                using (var db = new LiteDatabase(datasource))
                {
                    db.Rebuild();
                }
            }
            catch (Exception ex)
            {
               // LogHelper.Error("重建数据库文件(收缩文件大小)异常", ex);
            }
        }

        public void Dispose()
        {
            using (var db = new LiteDatabase(datasource))
            {
                db.Dispose();
            }
        }
    }
}